#ifndef GML__LIST_H
#define GML__LIST_H

#include <stdbool.h>
#include <stddef.h>

#define ListType(_Type) List##_Type

#define ListFunc(_Func) list##_Func

#define ListAlgo(_Algo) _Algo##Bidirectional

typedef struct ListNode ListNode;

typedef struct {
	ListNode *listNode_;
} ListIterator;

typedef struct {
	const ListNode *listNode_;
} ListConstIterator;

bool listIteratorEqualTo(const ListIterator *_this, const ListIterator *_listIterator);

bool listIteratorNotEqualTo(const ListIterator *_this, const ListIterator *_listIterator);

int *listIteratorIndirect(const ListIterator *_this);

ListIterator *listIteratorIncreasePrefix(ListIterator *_this);

ListIterator listIteratorIncreasePostfix(ListIterator *_this);

ListIterator *listIteratorDecreasePrefix(ListIterator *_this);

ListIterator listIteratorDecreasePostfix(ListIterator *_this);

typedef struct List {
	ListNode *listNode_;
} List;

List *listNew();

void listDelete(List *_this);

void listConstruct(List *_this);

void listDestruct(List *_this);

ListIterator listBegin(const List *_this);

ListIterator listEnd(const List *_this);

bool listInsert(ListIterator _position, int _value);

bool listInsertN(ListIterator _position, size_t _n, int _value);

bool listInsertIn(ListIterator _position, ListIterator _first, ListIterator _last);

void listErase(ListIterator _position);

void listEraseN(ListIterator _position, size_t _n);

void listEraseIn(ListIterator _first, ListIterator _last);

void listSplice(ListIterator _position, ListIterator _listIterator);

void listSpliceN(ListIterator _position, ListIterator _listIterator, size_t _n);

void listSpliceIn(ListIterator _position, ListIterator _first, ListIterator _last);

bool listEmpty(const List *_this);

size_t listSize(const List *_this);

void listClear(const List *_this);

ListIterator listMarge(ListIterator _first1, ListIterator _last1, ListIterator _first2, ListIterator _last2);

ListIterator listSort(ListIterator _first, ListIterator _last);

#endif // GML__LIST_H
